﻿using CommonLib.Attr;
using CommonLib.Base;
using CommonLib.CodeEntity;
using CommonLib.Util;
using System.Text.RegularExpressions;

namespace Oracle.Lexer;

[Order(0)]
public sealed class TableLexer : BaseLexer
{
    public override bool Check()
        => Regex.IsMatch(Txt, "CREATE.*?TABLE");

    protected override BaseCodeEntity Run()
    {
        var tbl = Txt.Replace("\"", "");
        var name = tbl[..tbl.IndexOf("(")].Trim();
        name = name[(name.IndexOf(".") + 1)..].Trim();
        var entity = new TableCodeEntity(name);
        var pk = tbl.Contains("PRIMARY KEY") ? Regex.Match(tbl, "PRIMARY KEY\\s*\\((.*?)\\)").Result("$1") : "";
        if (!string.IsNullOrEmpty(pk)) entity.PrimayKey = pk;
        string? cols;
        if (tbl.Contains(" SEGMENT")) cols = Regex.Match(tbl, "\\((.*?)\\) SEGMENT").Result("$1");
        else cols =Regex.Match(tbl, "\\((.*)\\)").Result("$1");
        if (cols.Contains("CONSTRAINT"))
        {
            cols = Regex.Match(cols, "(.*?),\\s*CONSTRAINT").Result("$1");
        }
        var arr = cols.TrimSplit(',');
        for (int i = 0; i < arr.Length; i++)
        {
            var item = arr[i];
            while (!item.IsFull())
            {
                var next = arr[++i];
                item = string.Format("{0},{1}", item, next);
            }
            if (!string.IsNullOrEmpty(item.Trim()))
            {
                entity.Columns.Add(ColumnLexer(item));
            }
        }       
        return entity;
    }


    private ColumnCodeEntity ColumnLexer(string col)
    {
        var arr = col.TrimSplit(' ').Select(a => a.Trim())
            .Where(a => !string.IsNullOrEmpty(a)).ToList();
        var entity = new ColumnCodeEntity(arr[0], arr[1], col.Contains("NOT NULL"));
        var idx = arr.FindIndex(a => a.Equals("DEFAULT"));
        if (idx > 0)
        {
            var val = arr[idx + 1];
            if (val.StartsWith("(") && val.EndsWith(")")) val = val[1..^1];
            entity.DeflutValue = SqlFactory.Create(val).Execute();
        }
        return entity;
    }
}
